/* ============================================================
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
* Copyright (C) 2011-2013 QuiteRSS Team <quiterssteam@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "updatedelayer.h"

#include <QApplication>

#define UPDATE_INTERVAL 3000
#define MIN_UPDATE_INTERVAL 500

UpdateDelayer::UpdateDelayer(QObject *parent, int delayValue)
  : QObject(parent)
  , delayValue_(delayValue)
  , nextUpdateFeed_(true)
{
  delayTimer_ = new QTimer(this);
  delayTimer_->setSingleShot(true);
  connect(delayTimer_, SIGNAL(timeout()), this, SLOT(slotDelayTimerTimeout()));

  updateModelTimer_ = new QTimer(this);
  updateModelTimer_->setSingleShot(true);
  connect(updateModelTimer_, SIGNAL(timeout()), this, SIGNAL(signalUpdateModel()));
}

/** @brief Обработка постановки Id-ленты в очередь на обновление
 *
 *  Лента добавляется в очередь и запускается таймер, если он ещё не запущен
 * @param feedId Id-ленты
 * @param feedChanged Флаг того, что ленты действительно изменялась
 *---------------------------------------------------------------------------*/
void UpdateDelayer::delayUpdate(const QString &feedUrl, const bool &feedChanged, int newCount)
{
  if (!feedChanged) {
    emit signalUpdateNeeded(feedUrl, feedChanged, newCount);
    return;
  }

  int feedIdIndex = feedUrlList_.indexOf(feedUrl);
  // Если лента уже есть в списке
  if (-1 < feedIdIndex) {
    // Если лента изменялясь, то устанавливаем этот флаг принудительно
    if (feedChanged) {
      feedChangedList_[feedIdIndex] = feedChanged;  // i.e. true
      newCountList_[feedIdIndex] = newCount;
    }
  }
  // иначе добавляем ленту
  else {
    feedUrlList_.append(feedUrl);
    feedChangedList_.append(feedChanged);
    newCountList_.append(newCount);
  }

  // Запуск таймера, если добавили первую ленту в список
  // Своеобразная защита от запуска во время обработки таймаута
  if ((feedUrlList_.size() == 1) && nextUpdateFeed_) {
    nextUpdateFeed_ = false;
    delayTimer_->start(0);

    if (!updateModelTimer_->isActive()) {
      updateModelTimer_->start(MIN_UPDATE_INTERVAL);
    } else {
      if (updateModelTimer_->interval() == MIN_UPDATE_INTERVAL) {
        updateModelTimer_->start(UPDATE_INTERVAL - MIN_UPDATE_INTERVAL);
      }
    }
  }

}

/** @brief Обработка срабатывания таймера
 *
 *  Производится обновление следующей в очереди ленты
 *---------------------------------------------------------------------------*/
void UpdateDelayer::slotDelayTimerTimeout()
{
  QString feedUrl = feedUrlList_.takeFirst();
  bool feedChanged = feedChangedList_.takeFirst();
  int newCount = newCountList_.takeFirst();
  emit signalUpdateNeeded(feedUrl, feedChanged, newCount);
}

/** @brief Запуск таймера при наличии в очереди лент
 *---------------------------------------------------------------------------*/
void UpdateDelayer::slotNextUpdateFeed()
{
  qApp->processEvents();  // при перемещении окна оно не перерисовывается о_О
  if (feedUrlList_.size()) {
    delayTimer_->start(delayValue_);

    if (!updateModelTimer_->isActive())
      updateModelTimer_->start(UPDATE_INTERVAL);
  } else {
    nextUpdateFeed_ = true;

   if (!updateModelTimer_->isActive())
      updateModelTimer_->start(MIN_UPDATE_INTERVAL);
  }
}
